#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FILE_NAME	"names.txt"
#define FALSE	0
#define TRUE	1


struct node {
	int n;
	struct node* next;
};

int get_data(void)
{
	int n;
	char r;
	printf ("Enter number: ");
	scanf ("%d", &n);
	scanf ("%c", &r);
	return n;
}

int show_list(struct node* l)
{
	struct node* aux;
	int n;
	n = 0;
	aux = l;
	if (aux == NULL){
		printf ("The list is empty.\n");
		return 1;
	}
	while (aux != NULL){
		printf("%d\t", aux->n);
		n++;
		aux = aux->next;
	}
	printf ("\n");
	printf("List has %d node(s).\n", n);
	return 0;
}
int count_list(struct node* l)
{
	struct node* aux;
	int i;
	i = 0;
	aux = l;
	while (aux != NULL){
		aux = aux->next;
		i++;
	}
	return i;
	
}
int insert_back(struct node** l)
{
	struct node* aux;
	struct node* aux2;
	aux = (struct node*) malloc(sizeof(struct node));
	aux->n = get_data();
	aux->next = NULL;

	if (*l == NULL){
		/*List is empty*/
		*l = aux;
	}
	else {
		aux2 = *l;
		while (aux2->next != NULL){
			aux2 = aux2->next;
		}
		aux2->next = aux;
	}
	return 0;
}
int insert_front(struct node** l)
{
	struct node* aux;
	aux = (struct node*) malloc(sizeof(struct node));
	aux->n = get_data();
	

	if (*l == NULL){
		*l = aux;
		(**l).next = NULL;	
	}
	else {
		aux->next = *l;
		*l = aux;
	}
	return 0;
}
int insert_order(struct node** l)
{
struct node* new;
	struct node* aux;
	new = (struct node*) malloc(sizeof(struct node));
	new->n = get_data();
	new->next = NULL;
	aux = *l;
	if (*l == NULL){
		*l = new;
	}
	else {
		if (aux->n > new->n){
			new->next = aux;
			*l = new;
		}	
		else {
			while (aux->next != NULL &&  new->n >= aux->next->n){
				aux = aux->next;
			}
			new->next = aux->next;
			aux->next = new;	
		}
	}
	return 0;
}
int delete_node(struct node** l)
{
	struct node* aux;
	struct node* del;
	int number;
	if (*l == NULL){
		printf ("The list is empty.\n");
		return 1;
	}
	aux = *l;
	printf ("Enter the number to be deleted:");
	scanf ("%d", &number);
	if (aux->n == number){
		del = *l;
		*l = aux->next;
		free(del);
	}
	else {
		while (aux->next->n != number){ 
			if (aux->next == NULL){
				printf("Node not find.\n");
				return 1;
			}
			aux = aux->next;
		}
		del = aux->next;
		aux->next = aux->next->next;
		free(del);
	}
	return 0;
}
int menu(void)
{
	int option;
	printf ("Enter (1) to add node to the front.\n");
	printf ("Enter (2) to add node to the back.\n");
	printf ("Enter (3) to add node in order.\n");
	printf ("Enter (4) to del node.\n");
	printf ("Enter (5) to show list.\n");
	printf ("Enter (0) to exit:");
	scanf ("%d", &option);
	return option;
}
int init_file(FILE* file, struct node** l)
{
	struct node* aux;
	struct node tmp;
	int n, out, i;
	out = FALSE;
	aux = *l;
	i = 0;
	do {
		n = fread(&tmp, sizeof(struct node), 1, file);
		if (n <= 0){
			out = TRUE;
		}
		else {
			if (*l == NULL){
				*l = (struct node*) malloc(sizeof(struct node));
				aux = *l;
				memset (aux, 0, sizeof(struct node));
				*aux = tmp;
				aux->next = NULL;
				i++;
			}
			else {
				while (aux->next != NULL){
					aux = aux->next;
				}
				aux->next = (struct node*) malloc(sizeof(struct node));
				memset (aux, 0, sizeof(struct node));
				aux = aux->next;
				*aux = tmp;
				aux->next = NULL;
				i++;
			}
		}
	} while (out == FALSE);
	return 0;
}
int record_data(struct node** l)
{
	struct node* aux;
	FILE* file;
	int n, i;
	
	aux = *l;
	if ((file = fopen(FILE_NAME, "wb")) == NULL){
		printf (stderr, "Problem opening the file.\n");
		return 1;
	}
	n = count_list(*l);
	
	//	i = fwrite (aux, sizeof(struct node), n, file);
	if (i != n){
		printf (" i != n\n");
		printf (stderr, "Problem writing struct to the file.\n");
	}
	else {
		printf ("%d structs written.\n", i);
	}
	return 0;
}
int main(void){
	struct node* list;
	FILE* file;
	list = NULL;
	int choice;
	if ((file = fopen(FILE_NAME, "rb")) == NULL){
		printf ("First time use.\n");
	}
	else {
		init_file(file, &list);
	}

	do {
		choice = menu();
		switch (choice){
			case 1:
				insert_front(&list);
				break;
			case 2:
				insert_back(&list);
				break;
			case 3:
				insert_order(&list);
				break;
			case 4:
				delete_node(&list);
				break;
			case 5:
				show_list(list);
				break;
			case 0:
				record_data(&list);
				return 0;
				break;
			default:
				printf ("Option not found. Try again.\n");
				continue;
		}
	} while (choice != 0);
	return 0;
}
